package com.h3c.ptability.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eos.common.util.IdWorker;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.h3c.ptability.entity.PtFileTemplate;
import com.h3c.ptability.mapper.PtFileTemplateMapper;
import com.h3c.ptability.service.IPtFileTemplateService;
import com.h3c.ptability.dto.PtFileTemplateDTO;
import com.h3c.ptability.utils.AppBusinessException;
import com.h3c.ptability.utils.CommonUtil;
import com.h3c.ptability.utils.ErrorCodeEnum;
import com.h3c.ptability.utils.InitExampleOrderByUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Copyright (C), 2020-2020, h3c
 * FileName: PtFileTemplateServiceImpl
 *
 * @Author: l22886
 * @Date: 2022-03-14
 * Description: pt_file_template serviceImpl
 * Version: 1.0
 */
@Slf4j
@Service
public class PtFileTemplateServiceImpl extends ServiceImpl<PtFileTemplateMapper, PtFileTemplate> implements IPtFileTemplateService {

    @Resource
    private PtFileTemplateMapper ptFileTemplateMapper;

    

    /**
     * @title: selectFuzzyByDto
     * @description: 模糊查询操作
     * @params: [ dto ]
     * @return: java.util.List
     * @createTime: 2022-03-14
     * @version: 1.0
     * @author: l22886
     */
    @Override
    public List<PtFileTemplateDTO> selectFuzzyByDto(PtFileTemplateDTO dto) {
        //List<PtFileTemplate> list = ptFileTemplateMapper.selectByExample(initFuzzyExample(dto));
        List<PtFileTemplate> list = ptFileTemplateMapper.queryListByFuzzy(JSONObject.parseObject(JSONObject.toJSONString(dto),PtFileTemplate.class));
        return JSONArray.parseArray(JSONArray.toJSONString(list), PtFileTemplateDTO.class);
    }

    /**
     * @title: selectByDto
     * @description: 精确查询操作
     * @params: [ dto ]
     * @return: java.util.List
     * @createTime: 2022-03-14
     * @version: 1.0
     * @author: l22886
     */
    @Override
    public List<PtFileTemplateDTO> selectByDto(PtFileTemplateDTO dto) {
        //List<PtFileTemplate> list = ptFileTemplateMapper.selectByExample(initExample(dto));
        List<PtFileTemplate> list = ptFileTemplateMapper.queryList(JSONObject.parseObject(JSONObject.toJSONString(dto),PtFileTemplate.class));
        return JSONArray.parseArray(JSONArray.toJSONString(list), PtFileTemplateDTO.class);
    }

    /**
     * @title: insertDto
     * @description: 插入操作
     * @params: [ dto ]
     * @return: Integer
     * @createTime: 2022-03-14
     * @version: 1.0
     * @author: l22886
     */
    @Override
    public Integer insertDto(PtFileTemplateDTO dto) {
        //if (null == dto.getId() || "".equals(dto.getId())) {
        //    String pkId = idWorker.nextId() + "";
        //    dto.setId(pkId);
        //}
        return ptFileTemplateMapper.insertPtFileTemplate(JSONObject.parseObject(JSON.toJSONString(dto), PtFileTemplate.class));
    }

    /**
     * @title: updateDto
     * @description: 修改操作
     * @params: [ dto ]
     * @return: Integer
     * @createTime: 2022-03-14
     * @version: 1.0
     * @author: l22886
     */
    @Override
    public Integer updateDto(PtFileTemplateDTO dto) {
        //if (null != dto && null != dto.getId() && !"".equals(dto.getId())) {
            return ptFileTemplateMapper.updatePtFileTemplate(JSONObject.parseObject(JSON.toJSONString(dto), PtFileTemplate.class));
            //return ptFileTemplateMapper.updateByPrimaryKey(JSONObject.parseObject(JSON.toJSONString(dto), PtFileTemplate.class));
        //} else {
        //    return 0;
        //}
    }

    /**
     * @title: deleteDto
     * @description: 删除操作
     * @params: [ dto ]
     * @return: Integer
     * @createTime: 2022-03-14
     * @version: 1.0
     * @author: l22886
     */
    @Override
    public Integer deleteDto(PtFileTemplateDTO dto) {
        //if (null != dto && null != dto.getId() && !"".equals(dto.getId())) {
            return ptFileTemplateMapper.deletePtFileTemplate(JSONObject.parseObject(JSON.toJSONString(dto), PtFileTemplate.class));
            //return ptFileTemplateMapper.deleteByPrimaryKey(dto.getId());
        //} else {
        //    return 0;
        //}
    }

    @Override
    public PtFileTemplate queryTemplateByCode(String templateCode,String appId) {
        QueryWrapper<PtFileTemplate> wrapper = new QueryWrapper<>();
        wrapper.eq("template_code", templateCode)
                .eq("app_id",appId);
        return getOne(wrapper);
    }


    @Override
    public PtFileTemplate queryTemplateByCode(String templateCode) {
        QueryWrapper<PtFileTemplate> wrapper = new QueryWrapper<>();
        wrapper.eq("template_code", templateCode);
        return getOne(wrapper);
    }

    @Override
    public Map<String, Object> queryTemplate(String templateCode,String appId) {
        try {
            PtFileTemplate ptFileTemplate = queryTemplateByCode(templateCode,appId);
            if(ptFileTemplate == null){
                throw new AppBusinessException("excel模板[code:"+templateCode+"]不存在");
            }
            //String templateId = ptFileTemplate.getFileTemplateId();
            String fileNameWithPah = ptFileTemplate.getTemplateFilePath();
            String fileName = fileNameWithPah.substring(fileNameWithPah.lastIndexOf("\\") + 1);
            fileName = ptFileTemplate.getTemplateName() + fileName.substring(fileName.lastIndexOf("."));

//            File downloadFile = new File(fileNameWithPah);
//            FileInputStream inputFile = new FileInputStream(downloadFile);
            byte[] buffer = ptFileTemplate.getTemplateFile();
//            inputFile.read(buffer);
//            inputFile.close();
            Map<String, Object> result = new HashMap<String, Object>();
            result.put("file", Base64Utils.encodeToString(buffer));
            result.put("filename", fileName);
            result.put("startRow", ptFileTemplate.getStartRow());
            result.put("startCol", ptFileTemplate.getStartCol());
            result.put("colSize", ptFileTemplate.getColSize());
            result.put("fieldContent", ptFileTemplate.getFieldContent());
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("模板文件获取异常");
        }
    }


    /**
     * @title: initFuzzyExample
     * @description: 初始化 模糊查询 example
     * @params: [ dto ]
     * @return: tk.mybatis.mapper.entity.Example
     * @createTime: 2022-03-14
     * @version: 1.0
     * @author: l22886
     */
    private Example initFuzzyExample(PtFileTemplateDTO dto) {
        Example example = InitExampleOrderByUtils.initExampleOrderBy(PtFileTemplate.class, dto.getOrderBy());
        Example.Criteria criteriaName = example.createCriteria();
        if (null != dto) {
            if (null != dto.getFileTemplateId() && !"".equals(dto.getFileTemplateId())) {
                criteriaName.andLike("FileTemplateId", "%" + dto.getFileTemplateId() + "%");
            }
            if (null != dto.getAppId() && !"".equals(dto.getAppId())) {
                criteriaName.andLike("AppId", "%" + dto.getAppId() + "%");
            }
            if (null != dto.getTemplateName() && !"".equals(dto.getTemplateName())) {
                criteriaName.andLike("TemplateName", "%" + dto.getTemplateName() + "%");
            }
            if (null != dto.getTemplateCode() && !"".equals(dto.getTemplateCode())) {
                criteriaName.andLike("TemplateCode", "%" + dto.getTemplateCode() + "%");
            }
            if (null != dto.getTemplateType() && !"".equals(dto.getTemplateType())) {
                criteriaName.andLike("TemplateType", "%" + dto.getTemplateType() + "%");
            }
            if (null != dto.getStartRow() && !"".equals(dto.getStartRow())) {
                criteriaName.andLike("StartRow", "%" + dto.getStartRow() + "%");
            }
            if (null != dto.getStartCol() && !"".equals(dto.getStartCol())) {
                criteriaName.andLike("StartCol", "%" + dto.getStartCol() + "%");
            }
            if (null != dto.getColSize() && !"".equals(dto.getColSize())) {
                criteriaName.andLike("ColSize", "%" + dto.getColSize() + "%");
            }
            if (null != dto.getFieldContent() && !"".equals(dto.getFieldContent())) {
                criteriaName.andLike("FieldContent", "%" + dto.getFieldContent() + "%");
            }
            if (null != dto.getTemplateFilePath() && !"".equals(dto.getTemplateFilePath())) {
                criteriaName.andLike("TemplateFilePath", "%" + dto.getTemplateFilePath() + "%");
            }
            if (null != dto.getTemplateFile() && !"".equals(dto.getTemplateFile())) {
                criteriaName.andLike("TemplateFile", "%" + dto.getTemplateFile() + "%");
            }
            if (null != dto.getOrigTemplateFile() && !"".equals(dto.getOrigTemplateFile())) {
                criteriaName.andLike("OrigTemplateFile", "%" + dto.getOrigTemplateFile() + "%");
            }
        }
        return example;
    }

    /**
     * @title: initExample
     * @description: 初始化 精确查询 example
     * @params: [ dto ]
     * @return: tk.mybatis.mapper.entity.Example
     * @createTime: 2022-03-14
     * @version: 1.0
     * @author: l22886
     */
    private Example initExample(PtFileTemplateDTO dto) {
        Example example = InitExampleOrderByUtils.initExampleOrderBy(PtFileTemplate.class, dto.getOrderBy());
        Example.Criteria criteriaName = example.createCriteria();
        if (null != dto) {
            if (null != dto.getFileTemplateId() && !"".equals(dto.getFileTemplateId())) {
                criteriaName.andEqualTo("FileTemplateId", dto.getFileTemplateId());
            }
            if (null != dto.getAppId() && !"".equals(dto.getAppId())) {
                criteriaName.andEqualTo("AppId", dto.getAppId());
            }
            if (null != dto.getTemplateName() && !"".equals(dto.getTemplateName())) {
                criteriaName.andEqualTo("TemplateName", dto.getTemplateName());
            }
            if (null != dto.getTemplateCode() && !"".equals(dto.getTemplateCode())) {
                criteriaName.andEqualTo("TemplateCode", dto.getTemplateCode());
            }
            if (null != dto.getTemplateType() && !"".equals(dto.getTemplateType())) {
                criteriaName.andEqualTo("TemplateType", dto.getTemplateType());
            }
            if (null != dto.getStartRow() && !"".equals(dto.getStartRow())) {
                criteriaName.andEqualTo("StartRow", dto.getStartRow());
            }
            if (null != dto.getStartCol() && !"".equals(dto.getStartCol())) {
                criteriaName.andEqualTo("StartCol", dto.getStartCol());
            }
            if (null != dto.getColSize() && !"".equals(dto.getColSize())) {
                criteriaName.andEqualTo("ColSize", dto.getColSize());
            }
            if (null != dto.getFieldContent() && !"".equals(dto.getFieldContent())) {
                criteriaName.andEqualTo("FieldContent", dto.getFieldContent());
            }
            if (null != dto.getTemplateFilePath() && !"".equals(dto.getTemplateFilePath())) {
                criteriaName.andEqualTo("TemplateFilePath", dto.getTemplateFilePath());
            }
            if (null != dto.getTemplateFile() && !"".equals(dto.getTemplateFile())) {
                criteriaName.andEqualTo("TemplateFile", dto.getTemplateFile());
            }
            if (null != dto.getOrigTemplateFile() && !"".equals(dto.getOrigTemplateFile())) {
                criteriaName.andEqualTo("OrigTemplateFile", dto.getOrigTemplateFile());
            }
        }
        return example;
    }

    /**
     * 新增或修改excel模板
     * @param pdFileTemplateDTO
     */
    @Override
    public void addPtFileTemplate(PtFileTemplateDTO pdFileTemplateDTO) {

        if ("true".equals(pdFileTemplateDTO.getModifyFlag())) {
            //修改模板
            String fileTemplateId = pdFileTemplateDTO.getFileTemplateId();
            PtFileTemplate pdFileTemplate = new PtFileTemplate();
            String fileContent = parseTemplateFile(pdFileTemplateDTO, fileTemplateId);
            BeanUtils.copyProperties(pdFileTemplateDTO, pdFileTemplate);
            pdFileTemplate.setFieldContent(fileContent);
            pdFileTemplate.setFileTemplateId(fileTemplateId);
            ptFileTemplateMapper.updatePtFileTemplate(pdFileTemplate);
        } else {
            String templateName = pdFileTemplateDTO.getTemplateName();
            String templateCode = pdFileTemplateDTO.getTemplateCode();
            List<PtFileTemplate> existsList = ptFileTemplateMapper.queryFileTemplateList(templateName, templateCode);
            if (existsList != null && existsList.size() > 0) {
                throw new AppBusinessException(ErrorCodeEnum.TEMPLATE_NAME_EXISTS);
            }
            if (pdFileTemplateDTO.getUploadTemplateFile() == null) {
                throw new AppBusinessException(ErrorCodeEnum.TEMPLATE_NOT_EXISTS);
            }
            String templateId = IdWorker.nextId() + "";
            String fileContent = parseTemplateFile(pdFileTemplateDTO, templateId);
            PtFileTemplate pdFileTemplate = new PtFileTemplate();
            BeanUtils.copyProperties(pdFileTemplateDTO, pdFileTemplate);
            pdFileTemplate.setFieldContent(fileContent);
            pdFileTemplate.setFileTemplateId(templateId);
            save(pdFileTemplate);
        }
    }

    @Override
    public String addPtFileTemplateReturnId(PtFileTemplateDTO pdFileTemplateDTO) {
        PtFileTemplate pdFileTemplate;
        if ("true".equals(pdFileTemplateDTO.getModifyFlag())) {
            //修改模板
            String fileTemplateId = pdFileTemplateDTO.getFileTemplateId();
            pdFileTemplate = new PtFileTemplate();
            String fileContent = parseTemplateFile(pdFileTemplateDTO, fileTemplateId);
            BeanUtils.copyProperties(pdFileTemplateDTO, pdFileTemplate);
            pdFileTemplate.setFieldContent(fileContent);
            pdFileTemplate.setFileTemplateId(fileTemplateId);
            ptFileTemplateMapper.updatePtFileTemplate(pdFileTemplate);
        } else {
            String templateName = pdFileTemplateDTO.getTemplateName();
            String templateCode = pdFileTemplateDTO.getTemplateCode();
            List<PtFileTemplate> existsList = ptFileTemplateMapper.queryFileTemplateList(templateName, templateCode);
            if (existsList != null && existsList.size() > 0) {
                throw new AppBusinessException(ErrorCodeEnum.TEMPLATE_NAME_EXISTS);
            }
            if (pdFileTemplateDTO.getUploadTemplateFile() == null) {
                throw new AppBusinessException(ErrorCodeEnum.TEMPLATE_NOT_EXISTS);
            }
            String templateId = IdWorker.nextId() + "";
            String fileContent = parseTemplateFile(pdFileTemplateDTO, templateId);
            pdFileTemplate = new PtFileTemplate();
            BeanUtils.copyProperties(pdFileTemplateDTO, pdFileTemplate);
            pdFileTemplate.setFieldContent(fileContent);
            pdFileTemplate.setFileTemplateId(templateId);
            save(pdFileTemplate);
        }
        return pdFileTemplate.getFileTemplateId();
    }

    private String parseTemplateFile(PtFileTemplateDTO dto, String templateId) {
        int startRow = dto.getStartRow() - 1;
        int startCol = dto.getStartCol() - 1;
        int colSize = dto.getColSize();
        String filePath = null;
        MultipartFile uploadTemplateFile = dto.getUploadTemplateFile();
        if (uploadTemplateFile == null || uploadTemplateFile.getOriginalFilename().equals("")) {
            return "";
        }
        byte[] fileByteArray = null;
        try {
            fileByteArray = uploadTemplateFile.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String gradeSelectValues [] = {"A+","A","B+","B","C","D"};
        String cultureSelectValues [] = {"1级","2级","3级","4级"};
        String fileName = uploadTemplateFile.getOriginalFilename();
        String fileType = fileName.substring(fileName.lastIndexOf("."));

        int endCol = startCol + colSize;
        InputStream inputStream = null;
        StringBuilder sb = new StringBuilder();
        try {
            //1、获取文件输入流
            inputStream = uploadTemplateFile.getInputStream();
            //2、获取Excel工作簿对象
            Workbook workbook = null;
            if (fileType.toLowerCase().equals(".xlsx")) {
                workbook = new XSSFWorkbook(inputStream);
            } else {
                workbook = new HSSFWorkbook(inputStream);
            }
            //3、得到Excel工作表对象
            Sheet sheetAt = workbook.getSheetAt(0);
            //4、循环读取表格数据
            for (Row row : sheetAt) {
                //首行（即表头）不读取
                if (row.getRowNum() < startRow) {
                    continue;
                }

                for (int i = startCol; i < endCol; i++) {
                    if (row.getCell(i) != null && !row.getCell(i).getCellTypeEnum().equals(CellType.FORMULA)) {
                        row.getCell(i).setCellType(CellType.STRING);
                        String fieldName = row.getCell(i).getStringCellValue();
                        sb.append(fieldName).append(";");
                        if(fieldName.equals("curGrade") || fieldName.equals("kpiStage")){
                            CommonUtil.setSelectValueForColumn(sheetAt,i,gradeSelectValues);
                        }else if(fieldName.equals("curCulture")|| fieldName.equals("cultureStage")){
                            CommonUtil.setSelectValueForColumn(sheetAt,i,cultureSelectValues);
                        }
                        row.getCell(i).setCellValue("");
                    } else {
                        sb.append(";");
                    }
                }
                break;
            }
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                workbook.write(bos);
            } finally {
                bos.close();
            }
            //文件直接保存到数据库表里边，不在保存在服务器文件夹下了
            dto.setTemplateFile(bos.toByteArray());
            dto.setOrigTemplateFile(fileByteArray);
            //如果老模板存在，先删除老模板，再保存新模板
//            filePath = constuctFilePath(templateId, fileType);
//            File oldTemplate = new File(filePath);
//            if (oldTemplate.exists()) {
//                oldTemplate.delete();
//            }
            dto.setTemplateFilePath("\\" + templateId + fileType);
//            FileOutputStream out = new FileOutputStream(filePath);
//            workbook.write(out);
//            out.close();

            //5、关闭流
            workbook.close();

        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("导入模板,文件解析时出错");
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new RuntimeException("导入模板,保存模板文件时解析出错");
                }
                inputStream = null;
            }
        }
        String result = sb.toString();
        result = result.substring(0, result.length() - 1);
        return result;
    }


    @Override
    public void deletePtFileTemplate(PtFileTemplateDTO pdFileTemplateDTO) {
        String templateId = pdFileTemplateDTO.getFileTemplateId();
        //PtFileTemplate ptFileTemplate=ptFileTemplateMapper.selectOne(new QueryWrapper<PtFileTemplate>().eq("file_template_id",templateId));
        PtFileTemplate ptFileTemplate = getById(templateId);
        if (ptFileTemplate==null) {
            throw new AppBusinessException("excel模板[ID:"+templateId+"]不存在");
        }
        String filePath = ptFileTemplate.getTemplateFilePath();
        File delFile = new File(filePath);
        if (delFile.exists()) {
            delFile.delete();
        }
        delFile = null;
        removeById(templateId);
    }

    @Override
    public PtFileTemplate queryOrigFileTemplate(PtFileTemplateDTO pdFileTemplateDTO) {
        QueryWrapper<PtFileTemplate> wrapper = new QueryWrapper<>();
        wrapper.eq(!StringUtils.isEmpty(pdFileTemplateDTO.getTemplateCode()),"template_code", pdFileTemplateDTO.getTemplateCode())
                .eq(!StringUtils.isEmpty(pdFileTemplateDTO.getAppId()),"app_id",pdFileTemplateDTO.getAppId())
                .eq(!StringUtils.isEmpty(pdFileTemplateDTO.getFileTemplateId()),"file_template_id",pdFileTemplateDTO.getFileTemplateId());
        return getOne(wrapper);
    }
}
